/*
 * Config.java
 *
 * Created on 19.03.2005, 18:37
 *
 * Copyright (c) 2005-2007, Eugene Stahov (evgs), http://bombus-im.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * You can also redistribute and/or modify this program under the
 * terms of the Psi License, specified in the accompanied COPYING
 * file, as published by the Psi Project; either dated January 1st,
 * 2005, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

package Client;

import Info.Version;
import images.*;
import io.NvStorage;
import java.io.*;
import java.util.*;
import javax.microedition.lcdui.Font;
import midlet.Bombus;
import ui.FontCache;
import util.StringLoader;
import ui.Time;
import ui.VirtualElement;
import ui.VirtualList;
//import javax.microedition.rms.*;

/**
 *
 * @author Eugene Stahov
 */
public class Config {
    
    public final static int AWAY_OFF=0;
    public final static int AWAY_LOCK=1;
    public final static int AWAY_IDLE=2;

    
    public final int vibraLen=getIntProperty("vibra_len",500);
    
    //public int keepAlive=200;//getIntProperty("keep_alive",200);
    //public int keepAliveType=getIntProperty("keep_alive_type",0);

    /*public int socketLINGER=getIntProperty("LINGER",-1);
    public int socketRCVBUF=getIntProperty("RCVBUF",-1);
    public int socketSNDBUF=getIntProperty("SNDBUF",-1);*/

    public boolean ghostMotor=false;//getBooleanProperty("moto_e398",false);
    public boolean blFlash=!ghostMotor; //true;
    
    //public boolean msgLog=getBooleanProperty("msg_log",false); //<voffk>
    
    //public boolean muc119=getBooleanProperty("muc_119",true);	// before muc 1.19 use muc#owner instead of muc#admin //<voffk>
    
    public int soundsMsgIndex=0;

    public String messagesnd;
    public String messageSndType;
    
    public int soundVol=100;
    
    public char keyLock=getCharProperty("key_lock",'*');
    public char keyVibra=getCharProperty("key_vibra",'#');
    
    //public char keyHide=getCharProperty("key_hide",'9'); <voffk>
    public char keyOfflines=getCharProperty("key_offlines",'0');
        
    //public String defGcRoom=getStringProperty("gc_room","bombus@conference.jabber.ru"); //<voffk>
    
    //public String xmlLang=getStringProperty("xml_lang",null);
    
    // non-volatile values
    //public TimeZone tz=new RuGmt(0);
    public int accountIndex=-1;
    public boolean fullscreen=false;
    public int def_profile=0;
    public boolean smiles=true;
    public boolean showOfflineContacts=true;
//#if !ReleaseZVOFFK
    public boolean showTransports=true;
    public boolean selfContact=true;
    public boolean notInListPresences=true;
//#endif
    //public boolean notInList=true;
    //public int notInListDropLevel=NotInListFilter.ALLOW_ALL; //enable all //<voffk>
    public boolean ignore=false;
    public boolean eventComposing=false;
    
    public boolean eventDelivery=true;
    
    public boolean storeConfPresence=true;      
    
    public boolean autoLogin=false;
    public boolean autoJoinConferences=false;
    
    public boolean autoFocus=false;
    
	
    public int gmtOffset;
    public int locOffset;
    
    public boolean popupFromMinimized=true;
    public boolean memMonitor=true; //<*voffk>
    
    public int font1=0;
    public int font2=0;
    public int font3=0;

    public int colorTheme=0;  //default
    
    public String lang;  //en
    public boolean capsState=false; //FS#748
    public int textWrap=0;
    
    public boolean autoSubscribe=false;
    
    public int autoAwayType=0;
    public int autoAwayDelay=5; //5 minutes
    
    public boolean enableVersionOs=true;
    
    public int messageCollapsedLength=1000; //<*voffk>
    
    //public boolean enablePep=true;
    
    //<voffk>
//#ifdef PEP
    public boolean enableMood=true;
 //#if PEP_TUNE
    public boolean enableTune=false;
 //#endif
//#endif
    
    public boolean lastAppearedContacts=false;
    public int def_status=0;
    public int maxReconnect=10;
    public boolean useTabs=true;
    public boolean confirmDelete=true;
    public boolean autoScroll=false;
    public boolean accountSelect=false;
    
//#if ARCHIVE_ADVANCED
    public boolean cp1251=true;
//#endif
    
//#if TRAFFIC
//#     public boolean counterTraffic=false;
//#endif
    
//#if LIGHT_CONTROL
//#     public boolean lightState=false;
//#endif
    
//#if CLIPBOARD
//#     public boolean useClipBoard = true;
//#endif
    //</voffk>
    
    // runtime values
    public boolean allowMinimize=false;
    public int profile=0;
    public int lastProfile=0;
    
    public boolean istreamWaiting;
    

    // Singleton
    private static Config instance;

    public static Config getInstance(){
	if (instance==null) {
	    instance=new Config();
	    // this method called outside class constructor to avoid recursion
            // because using of NvStorage methods depending on Config.getInstance()
	    instance.loadFromStorage();
//#ifdef PEP            
            if (instance.enableMood) { //<voffk>
                //prefetch
                MoodIcons.getInstance();
            }
//#endif            
            
	    instance.loadSoundName();

            //FontCache.balloonFontSize=Font.SIZE_SMALL;
            FontCache.rosterFontSize=instance.font1;
            FontCache.msgFontSize=instance.font2;
            FontCache.resetCache();
	}
	return instance;
    }
    
    /** Creates a new instance of Config */
    private Config() {
     
        
	int gmtloc=TimeZone.getDefault().getRawOffset()/3600000;
	locOffset=getIntProperty( "time_loc_offset", 0);
	gmtOffset=getIntProperty("time_gmt_offset", gmtloc);
	
	int greenKeyCode=VirtualList.SIEMENS_GREEN;
	
	String platform=Version.getPlatformName();
	
	if (platform.startsWith("SonyE")) {
            //prefetch images
            RosterIcons.getInstance();
            SmilesIcons.getInstance();
            
	    allowMinimize=true;
            greenKeyCode=0;
            if (platform.startsWith("SonyEricssonM600")) VirtualList.keyBack=-11;
	}
	if (platform.startsWith("Nokia")) {
	    blFlash=false;
	    greenKeyCode=VirtualList.NOKIA_GREEN;
	}

	if (platform.startsWith("Motorola-EZX")) {
	    VirtualList.keyClear=0x1000;
	    VirtualList.keyVolDown=VirtualList.MOTOE680_VOL_DOWN;
	    VirtualList.keyBack=VirtualList.MOTOE680_REALPLAYER;
	} else
	if (platform.startsWith("Moto")) {
	    ghostMotor=true;
	    blFlash=false;
            istreamWaiting=true;
	    greenKeyCode=VirtualList.MOTOROLA_GREEN;
	    VirtualList.keyClear=0x1000;
	}
        //<voffk>
//#if !ZLIB
//#         if (platform.indexOf("9@9")>0) {
//#             istreamWaiting=false; //is it critical for phillips xenium?
//#         }
//#endif
        /*if (platform.startsWith("j2me")) {
	    greenKeyCode=VirtualList.MOTOROLA_GREEN;
	    VirtualList.keyClear=0x1000;
	    VirtualList.keyVolDown=VirtualList.MOTOE680_VOL_DOWN;
            istreamWaiting=true;
	}*/
        
        if (platform.startsWith("SIE")) {
            keyLock='#';
            keyVibra='*';
        }
        
	VirtualList.greenKeyCode=greenKeyCode;
    }
    
    protected void loadFromStorage(){
	try {
	    DataInputStream inputStream=NvStorage.ReadFileRecord("config", 0);
	    accountIndex = inputStream.readInt();
	    showOfflineContacts=inputStream.readBoolean();
	    fullscreen=inputStream.readBoolean();
	    def_profile = inputStream.readInt();
	    smiles=inputStream.readBoolean();
	    /*showTransports=inputStream.readBoolean();
	    selfContact=inputStream.readBoolean(); */ //<voffk>
	    // /*notInList=*/ inputStream.readBoolean(); */ <voffk>
	    ignore=inputStream.readBoolean();
	    eventComposing=inputStream.readBoolean();
	    
	    gmtOffset=inputStream.readInt();
	    locOffset=inputStream.readInt();
	    
	    soundsMsgIndex=inputStream.readInt();
	    soundVol=inputStream.readInt(); //<voffk>
            
	    autoLogin=inputStream.readBoolean();
	    autoJoinConferences=inputStream.readBoolean();
	    
	    //notInListDropLevel=inputStream.readInt(); <voffk>
	    
	    popupFromMinimized=inputStream.readBoolean();
	    
	    blFlash=inputStream.readBoolean();
	    //memMonitor=inputStream.readBoolean(); <voffk>
            
            font1=inputStream.readInt();
            font2=inputStream.readInt();
            
            autoFocus=inputStream.readBoolean();
            
            messageCollapsedLength=inputStream.readInt();
            
            storeConfPresence=inputStream.readBoolean();
            
            capsState=inputStream.readBoolean();
	    
	    textWrap=inputStream.readInt();
            
            autoSubscribe=inputStream.readBoolean();
            
            autoAwayType=inputStream.readInt();
            autoAwayDelay=inputStream.readInt();
            
            enableVersionOs=inputStream.readBoolean();
            
            lang=inputStream.readUTF();
            
            eventDelivery=inputStream.readBoolean();
            
            lastAppearedContacts=inputStream.readBoolean(); //<voffk>
            
//#if TRAFFIC
//#             counterTraffic=inputStream.readBoolean(); //<voffk>
//#else
            inputStream.readBoolean();
//#endif
            
            colorTheme=inputStream.readInt();
            
            def_status=inputStream.readInt(); //<voffk>
            
            maxReconnect=inputStream.readInt(); //<voffk>

//#if ARCHIVE_ADVANCED
            cp1251=inputStream.readBoolean(); //<voffk>
//#else
//#             inputStream.readBoolean();
//#endif

//#if LIGHT_CONTROL
//#             lightState=inputStream.readBoolean(); //<voffk>
//#else
            inputStream.readBoolean();
//#endif

//#if !ReleaseZVOFFK
            notInListPresences=inputStream.readBoolean();
            showTransports=inputStream.readBoolean();
            selfContact=inputStream.readBoolean();
//#else
//#             inputStream.readBoolean();
//#             inputStream.readBoolean();
//#             inputStream.readBoolean();
//#endif
            
            useTabs=inputStream.readBoolean(); //<voffk>
            
//#if PEP
            enableMood=inputStream.readBoolean();
 //#if PEP_TUNE
            enableTune=inputStream.readBoolean();
 //#else
//#             inputStream.readBoolean();
 //#endif
//#else
//#             inputStream.readBoolean();
//#             inputStream.readBoolean();
//#endif
            
//#if CLIPBOARD
//#             useClipBoard=inputStream.readBoolean();
//#else
            inputStream.readBoolean();
//#endif
            
            confirmDelete=inputStream.readBoolean(); //<+voffk>
            
            memMonitor=inputStream.readBoolean();
            
            autoScroll=inputStream.readBoolean(); //<+voffk>
            
            accountSelect=inputStream.readBoolean(); //<+voffk>
            
	    inputStream.close();
	} catch (Exception e) {
	    e.printStackTrace();
	}
	
	lastProfile=profile=def_profile;
        if (lastProfile==AlertProfile.VIBRA) lastProfile=0;
	updateTime();
	VirtualList.fullscreen=fullscreen;
	VirtualList.memMonitor=memMonitor;
    }
    
    public void loadSoundName(){
	Vector files[]=new StringLoader().stringLoader("/sounds/res.txt", 3);
        if (soundsMsgIndex>=files[0].size()) soundsMsgIndex=0;
	messageSndType=(String) files[0].elementAt(soundsMsgIndex);
	messagesnd=(String) files[1].elementAt(soundsMsgIndex);
    }
    
//#if !(ReleaseZLITE)
    public String langFileName(){
        if (lang==null) {
            //auto-detecting
            lang=System.getProperty("microedition.locale");
            System.out.println(lang);
            //We will use only language code from locale
            if (lang==null) lang="en"; else lang=lang.substring(0, 2).toLowerCase();
        }
        
        if (lang.equals("en")) return null;  //english
	Vector files[]=new StringLoader().stringLoader("/lang/res.txt", 3);
        for (int i=0; i<files[0].size(); i++) {
            String langCode=(String) files[0].elementAt(i);
            if (lang.equals(langCode))
        	return (String) files[1].elementAt(i);
        }
        return null; //unknown language ->en
    }
//#endif
    
//#if COLOR_THEMES
    public String themeFileName() {
        if (colorTheme==0) return null;   //default
        Vector files[]=new StringLoader().stringLoader("/themes/res.txt", 2);
        if (colorTheme>=files[0].size()) return null;
        return (String) files[0].elementAt(colorTheme);
    }
//#endif
    
    public void saveToStorage(){
	
	DataOutputStream outputStream=NvStorage.CreateDataOutputStream();
	
	try {
	    outputStream.writeInt(accountIndex);
	    outputStream.writeBoolean(showOfflineContacts);
	    outputStream.writeBoolean(fullscreen);
	    outputStream.writeInt(def_profile);
	    outputStream.writeBoolean(smiles);
	    /*outputStream.writeBoolean(showTransports);
	    outputStream.writeBoolean(selfContact); */ //<voffk>
	    //outputStream.writeBoolean(true /*notInList*/); <voffk>
	    outputStream.writeBoolean(ignore);
	    outputStream.writeBoolean(eventComposing);
	    
	    outputStream.writeInt(gmtOffset);
	    outputStream.writeInt(locOffset);
	    
	    outputStream.writeInt(soundsMsgIndex);
	    outputStream.writeInt(soundVol); //<voffk>
	    
	    outputStream.writeBoolean(autoLogin);
	    outputStream.writeBoolean(autoJoinConferences);
	    
	    //outputStream.writeInt(notInListDropLevel /*keepAlive*/); <voffk>

	    outputStream.writeBoolean(popupFromMinimized);
	    
	    outputStream.writeBoolean(blFlash);
	    //outputStream.writeBoolean(memMonitor); <voffk>
            
            outputStream.writeInt(font1);
            outputStream.writeInt(font2);
            
            outputStream.writeBoolean(autoFocus);
            
            outputStream.writeInt(messageCollapsedLength);
            
            outputStream.writeBoolean(storeConfPresence); 

            outputStream.writeBoolean(capsState); 
	    
	    outputStream.writeInt(textWrap);
            
            outputStream.writeBoolean(autoSubscribe);

            outputStream.writeInt(autoAwayType);
            outputStream.writeInt(autoAwayDelay);
            
            outputStream.writeBoolean(enableVersionOs);
            
            outputStream.writeUTF(lang);
            
            outputStream.writeBoolean(eventDelivery);
            
            outputStream.writeBoolean(lastAppearedContacts); //<voffk>
            
//#if TRAFFIC
//#             outputStream.writeBoolean(counterTraffic); //<voffk>
//#else
            outputStream.writeBoolean(false);
//#endif
            
            outputStream.writeInt(colorTheme);
            
            outputStream.writeInt(def_status); //<voffk>
            
            outputStream.writeInt(maxReconnect); //<voffk>

//#if ARCHIVE_ADVANCED
            outputStream.writeBoolean(cp1251); //<voffk>
//#else
//#             outputStream.writeBoolean(true);
//#endif

//#if LIGHT_CONTROL
//#             outputStream.writeBoolean(lightState); //<voffk>
//#else
            outputStream.writeBoolean(false);
//#endif

//#if !ReleaseZVOFFK
            outputStream.writeBoolean(notInListPresences);
            outputStream.writeBoolean(showTransports);
            outputStream.writeBoolean(selfContact);
//#else
//#             outputStream.writeBoolean(true);
//#             outputStream.writeBoolean(true);
//#             outputStream.writeBoolean(false);
//#endif

            outputStream.writeBoolean(useTabs); //<voffk>
            
//#if PEP
            outputStream.writeBoolean(enableMood);
 //#if PEP_TUNE
            outputStream.writeBoolean(enableTune);
 //#else
//#             outputStream.writeBoolean(false);
 //#endif
//#else
//#             outputStream.writeBoolean(true);
//#             outputStream.writeBoolean(false);
//#endif

//#if CLIPBOARD
//#             outputStream.writeBoolean(useClipBoard);
//#else
            outputStream.writeBoolean(true);
//#endif
            
            outputStream.writeBoolean(confirmDelete); //<+voffk>
            
            outputStream.writeBoolean(memMonitor);
            
            outputStream.writeBoolean(autoScroll); //<+voffk>
            
            outputStream.writeBoolean(accountSelect); //<+voffk>
            
	} catch (Exception e) { e.printStackTrace(); }
	
	NvStorage.writeFileRecord(outputStream, "config", 0, true);
    }
    
    
    public void updateTime(){
	Time.setOffset(gmtOffset, locOffset);
    }
    
    
    public final String getStringProperty(final String key, final String defvalue) {
	try {
	    String s=Bombus.getInstance().getAppProperty(key);
	    return (s==null)?defvalue:s;
	} catch (Exception e) {	}
        // возвращает defvalue, если атрибут не существует или имеет неправильный формат
        return defvalue;
    }
    
    public final int getIntProperty(final String key, final int defvalue) {
	try {
	    String s=Bombus.getInstance().getAppProperty(key);
	    return Integer.parseInt(s); //throws NullPointerException or NumberFormatException
	} catch (Exception e) { }
        // возвращает defvalue, если атрибут не существует или имеет неправильный формат
	return defvalue;
    }
    
    public final char getCharProperty(final String key, final char defvalue) {
	try {
	    String s=Bombus.getInstance().getAppProperty(key);
	    return s.charAt(0); //throws NullPointerException или IndexOutOfBoundsException
	} catch (Exception e) {	}
        // возвращает defvalue, если атрибут не существует или имеет неправильный формат
        return defvalue;
    }
    
    /*public final boolean getBooleanProperty(final String key, final boolean defvalue) {
	try {
	    String s=Bombus.getInstance().getAppProperty(key);
	    if (s.equals("true")) return true;
	    if (s.equals("yes")) return true;
	    if (s.equals("1")) return true;
            return false;
	} catch (Exception e) { }
        // возвращает defvalue, если атрибут не существует 
        return defvalue;
    }*/
    
}
